#include <iostream>
#include <unistd.h>
#include <pthread.h>
#include "RingQueue.hpp"
#include "Sem.hpp"

using namespace SemModule;

class ThreadInfo
{
public:
    RingQueue<int>* _rq;
    std::string _name;
};

void* consumer(void* args)
{
    ThreadInfo *rd = static_cast<ThreadInfo*>(args);

    while(true)
    {
        sleep(1);
        // 1. 消费任务 -- 从环形队列中取任务
        int x;
        rd->_rq->Pop(&x);

        // 2. 处理任务
        std::cout << rd->_name << "消费一个数据: " << x << std::endl;
    }
}

void* productor(void* args)
{
    ThreadInfo *rd = static_cast<ThreadInfo *>(args);
    int data = 0;
    while(true)
    {
        // 1. 获取任务
        std::cout << rd->_name << "生产一个数据: " << data << std::endl;

        // 2. 生产任务 -- 将数据放入环形队列中
        rd->_rq->Push(data++);
    }
}

int main()
{
    // 1. new 一个环形队列变量
    RingQueue<int>* rq = new RingQueue<int>();
    

    // 2. 创建生产者消费者线程
    pthread_t c[2], p[3];

    ThreadInfo *ri1 = new ThreadInfo();
    ri1->_rq = rq;
    ri1->_name = "Thread-1";
    pthread_create(c, nullptr, consumer, ri1);

    ThreadInfo *ri2 = new ThreadInfo();
    ri2->_rq = rq;
    ri2->_name = "Thread-2";
    pthread_create(c + 1, nullptr, consumer, ri2);

    ThreadInfo *ri3 = new ThreadInfo();
    ri3->_rq = rq;
    ri3->_name = "Thread-3";
    pthread_create(p, nullptr, productor, ri3);

    ThreadInfo *ri4 = new ThreadInfo();
    ri4->_rq = rq;
    ri4->_name = "Thread-4";
    pthread_create(p + 1, nullptr, productor, ri4);

    ThreadInfo *ri5 = new ThreadInfo();
    ri5->_rq = rq;
    ri5->_name = "Thread-5";
    pthread_create(p + 2, nullptr, productor, ri5);

    pthread_join(*c, nullptr);
    pthread_join(*(c+1), nullptr);
    pthread_join(*p, nullptr);
    pthread_join(*(p+1), nullptr);
    pthread_join(*(p+2), nullptr);
    return 0;
}